package com.miet.mp45.filippov.cryptoapplet.actionpanels;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.swing.JFileChooser;

import org.apache.log4j.Logger;

import com.miet.mp45.filippov.crypto.util.CryptoUtil;
import com.miet.mp45.filippov.cryptoapplet.actionpanels.events.ProcessingFinishedEventListener;
import com.miet.mp45.filippov.cryptoapplet.actionpanels.events.ProcessingStartedEventListener;
import com.miet.mp45.filippov.utils.IOUtilities;


public class SignFilePanel extends ActionPanel
{

    private static final long serialVersionUID = -7319106449479045327L;

    private Logger logger = Logger.getLogger(this.getClass());
    private javax.swing.JButton fileBrowseButton;
    private javax.swing.JTextField filePathTextField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JButton privateKeyBrowseButton;
    private javax.swing.JTextField privateKeyPathTextField;
    private javax.swing.JButton signButton;
    
    
    public SignFilePanel(ProcessingStartedEventListener pseListener,
                         ProcessingFinishedEventListener pfeListener)
    {
        addPSEListener(pseListener);
        addPFEListener(pfeListener);
        initComponents();
    }

    private void initComponents()
    {

        jLabel1 = new javax.swing.JLabel();
        privateKeyPathTextField = new javax.swing.JTextField();
        privateKeyBrowseButton = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        filePathTextField = new javax.swing.JTextField();
        fileBrowseButton = new javax.swing.JButton();
        signButton = new javax.swing.JButton();

        jLabel1.setText("KeyPair Path:");

        privateKeyBrowseButton.setText("...");
        privateKeyBrowseButton.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                privateKeyBrowseButtonActionPerformed(evt);
            }
        });

        jLabel2.setText("File to sign:");

        fileBrowseButton.setText("...");
        fileBrowseButton.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                fileBrowseButtonActionPerformed(evt);
            }
        });

        signButton.setText("Sign");
        signButton.addActionListener(new java.awt.event.ActionListener()
        {
            public void actionPerformed(java.awt.event.ActionEvent evt)
            {
                signButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        setLayout(layout);
        layout
                .setHorizontalGroup(layout
                        .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(
                                layout
                                        .createSequentialGroup()
                                        .addContainerGap()
                                        .addGroup(
                                                layout
                                                        .createParallelGroup(
                                                                javax.swing.GroupLayout.Alignment.LEADING,
                                                                false)
                                                        .addGroup(
                                                                layout
                                                                        .createSequentialGroup()
                                                                        .addComponent(jLabel1)
                                                                        .addPreferredGap(
                                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                        .addComponent(
                                                                                privateKeyPathTextField,
                                                                                javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                224,
                                                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                        .addPreferredGap(
                                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                        .addComponent(
                                                                                privateKeyBrowseButton))
                                                        .addGroup(
                                                                layout
                                                                        .createSequentialGroup()
                                                                        .addComponent(jLabel2)
                                                                        .addPreferredGap(
                                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED,
                                                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                                Short.MAX_VALUE)
                                                                        .addComponent(
                                                                                filePathTextField,
                                                                                javax.swing.GroupLayout.PREFERRED_SIZE,
                                                                                224,
                                                                                javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                        .addPreferredGap(
                                                                                javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                        .addComponent(
                                                                                fileBrowseButton))
                                                        .addComponent(
                                                                signButton,
                                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                                Short.MAX_VALUE)).addContainerGap(
                                                javax.swing.GroupLayout.DEFAULT_SIZE,
                                                Short.MAX_VALUE)));
        layout.setVerticalGroup(layout.createParallelGroup(
                javax.swing.GroupLayout.Alignment.LEADING).addGroup(
                layout.createSequentialGroup().addContainerGap().addGroup(
                        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jLabel1).addComponent(privateKeyPathTextField,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(
                                        privateKeyBrowseButton)).addPreferredGap(
                        javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addGroup(
                        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(jLabel2).addComponent(filePathTextField,
                                        javax.swing.GroupLayout.PREFERRED_SIZE,
                                        javax.swing.GroupLayout.DEFAULT_SIZE,
                                        javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(
                                        fileBrowseButton)).addPreferredGap(
                        javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(
                        signButton).addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
                        Short.MAX_VALUE)));

    }

    private void privateKeyBrowseButtonActionPerformed(java.awt.event.ActionEvent evt)
    {
        FILE_CHOOSER.setFileFilter(PRIVATE_KEY_FILE_FILTER);
        if (FILE_CHOOSER.showOpenDialog(this) == JFileChooser.APPROVE_OPTION)
        {
            privateKeyPathTextField.setText(FILE_CHOOSER.getSelectedFile().getAbsolutePath());
        }
    }

    private void fileBrowseButtonActionPerformed(java.awt.event.ActionEvent evt)
    {
        FILE_CHOOSER.setFileFilter(FILE_CHOOSER.getAcceptAllFileFilter());
        if (FILE_CHOOSER.showOpenDialog(this) == JFileChooser.APPROVE_OPTION)
        {
            filePathTextField.setText(FILE_CHOOSER.getSelectedFile().getAbsolutePath());
        }
    }

    private void signButtonActionPerformed(java.awt.event.ActionEvent evt)
    {
        final String filePath = filePathTextField.getText();
        final String privateKeyPath = privateKeyPathTextField.getText();
        
        if (filePath.isEmpty() || privateKeyPath.isEmpty())
        {
            return;
        }
        
        FILE_CHOOSER.setFileFilter(SIGNED_FILE_FILTER);
        if (FILE_CHOOSER.showSaveDialog(this) == JFileChooser.APPROVE_OPTION)
        {
            new CryptoTask()
            {
                @Override
                public void doRun()
                {
                    FileOutputStream fos = null;
                    try
                    {
                        File file = FILE_CHOOSER.getSelectedFile();
                        byte[] data = IOUtilities.readFile(filePath);
                        byte[] privateKey = IOUtilities.readFile(privateKeyPath);
                        logger.info("Signing file " + filePath + " ...");
                        byte[] signedData = CryptoUtil.sign(data, privateKey);
                        logger.info("Writing signed data into '" + file + "'");
                        fos = new FileOutputStream(file);
                        fos.write(signedData);
                    }
                    catch (Exception ex)
                    {
                        logger.error(ex);
                    }
                    finally
                    {
                        if (fos != null)
                        {
                            try { fos.close(); } catch (IOException ex) { logger.error(ex); }
                        }
                    }
                }
            }.start();
        }
    }

}
